home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / public / sox / echo.c < prev    next >
C/C++ Source or Header  |  1994-08-01  |  5KB  |  219 lines

  1.  
  2. /*
  3.  * July 5, 1991
  4.  * Copyright 1991 Lance Norskog And Sundry Contributors
  5.  * This source code is freely redistributable and may be used for
  6.  * any purpose.  This copyright notice must be maintained. 
  7.  * Lance Norskog And Sundry Contributors are not responsible for 
  8.  * the consequences of using this software.
  9.  */
  10.  
  11. /*
  12. **     Echo effect. based on:
  13. **
  14. ** echoplex.c - echo generator
  15. **
  16. ** Copyright (C) 1989 by Jef Poskanzer.
  17. **
  18. ** Permission to use, copy, modify, and distribute this software and its
  19. ** documentation for any purpose and without fee is hereby granted, provided
  20. ** that the above copyright notice appear in all copies and that both that
  21. ** copyright notice and this permission notice appear in supporting
  22. ** documentation.  This software is provided "as is" without express or
  23. ** implied warranty.
  24. */
  25.  
  26. /*
  27.  * Sound Tools echo effect file.
  28.  */
  29.  
  30. #ifdef    AMIGA
  31. #include <stdlib.h> /* Harmless, and prototypes atof() etc. --dgc */
  32. #endif
  33. #include <math.h>
  34. #include "st.h"
  35.  
  36. #define FADE_THRESH 10
  37. #define MYBUFSIZ 256
  38. #define DELAYBUFSIZ ( 50L * MAXRATE )
  39. #define MAXDELAYS 30
  40.  
  41. struct echoplex {
  42.     int    counter;            
  43.     int    numdelays;
  44.     long    *delaybuf;
  45.     float    delay[MAXDELAYS], atten[MAXDELAYS];
  46.     long    samples[MAXDELAYS], maxsamples;
  47.     long    pl, ppl, pppl;
  48. };
  49.  
  50. /* Private data for SKEL file */
  51. typedef struct echostuff {
  52.     struct    echoplex *echoplex;
  53. } *echo_t;
  54.  
  55. #ifndef abs
  56. #define abs(a) ((a) >= 0 ? (a) : -(a))
  57. #endif
  58.  
  59. long clip24();
  60.  
  61. IMPORT writing;
  62.  
  63. /*
  64.  * Process options
  65.  */
  66. echo_getopts(effp, n, argv) 
  67. eff_t effp;
  68. int n;
  69. char **argv;
  70. {
  71.     echo_t echo = (echo_t) effp->priv;
  72.     struct echoplex *e;
  73.     int i;
  74.  
  75.     echo->echoplex = (struct echoplex *) malloc(sizeof(struct echoplex));
  76.     e = echo->echoplex;
  77.     e->numdelays = 0;
  78.     e->maxsamples = 0;
  79.  
  80.     if ((n == 0) || (n & 1))
  81.         fail("Usage: echo delay attenuation [ delay attenuation ... ]");
  82.  
  83.     i = 0;
  84.     while (i < n) {
  85.     e->delay[e->numdelays] = atof( argv[i++] );
  86.     e->atten[e->numdelays] = atof( argv[i++] );
  87.  
  88.         e->numdelays++;
  89.     }
  90. }
  91.  
  92. /*
  93.  * Prepare for processing.
  94.  */
  95. echo_start(effp)
  96. eff_t effp;
  97. {
  98.     echo_t echo = (echo_t) effp->priv;
  99.     struct    echoplex *e = echo->echoplex;
  100.     int i;
  101.  
  102.     for(i = 0; i < e->numdelays; i++) {
  103.         e->samples[i] = e->delay[i] * effp->ininfo.rate;
  104.         if ( e->samples[i] < 1 )
  105.             fail(" delay must positive, aye!");
  106.         if ( e->samples[i] > DELAYBUFSIZ )
  107.             fail("Echo: delay must be less than %g seconds",
  108.                 DELAYBUFSIZ / (float) effp->ininfo.rate );
  109.         if ( e->atten[i] < 0.0 )
  110.             fail("attenuation must positive, aye!\n" );
  111.         if ( e->samples[i] > e->maxsamples )
  112.             e->maxsamples = e->samples[i];
  113.     }
  114.     if (! (e->delaybuf = (long *) malloc(sizeof (long) * e->maxsamples)))
  115.         fail("Echo: Cannot malloc %d bytes\n", 
  116.             sizeof(long) * e->maxsamples);
  117.     for ( i = 0; i < e->maxsamples; ++i )
  118.         e->delaybuf[i] = 0;
  119.     e->pppl = e->ppl = e->pl = 0x7fffff;        /* fade-outs */
  120.     e->counter = 0;
  121. }
  122.  
  123. /*
  124.  * Processed signed long samples from ibuf to obuf.
  125.  * Return number of samples processed.
  126.  */
  127.  
  128. echo_flow(effp, ibuf, obuf, isamp, osamp)
  129. eff_t effp;
  130. long *ibuf, *obuf;
  131. int *isamp, *osamp;
  132. {
  133.     echo_t echo = (echo_t) effp->priv;
  134.     struct    echoplex *e = echo->echoplex;
  135.     int len, done;
  136.     int i, j;
  137.     
  138.     long l;
  139.  
  140.     i = e->counter;
  141.     len = ((*isamp > *osamp) ? *osamp : *isamp);
  142.     for(done = 0; done < len; done++) {
  143.         /* Store delays as 24-bit signed longs */
  144.         l = *ibuf++ / 256;
  145.         for ( j = 0; j < e->numdelays; ++j )
  146.             l = l + 
  147. e->delaybuf[( i + e->maxsamples - e->samples[j]) % e->maxsamples] * e->atten[j];
  148.         l = clip24(l);
  149.         e->delaybuf[i] = l;
  150.         *obuf++ = l * 256;
  151.         i++;        /* XXX need a % maxsamples here ? */
  152.         i %= e->maxsamples;
  153.     }
  154.     e->counter = i;
  155.     /* processed all samples */
  156. }
  157.  
  158. /*
  159.  * Drain out echo lines. 
  160.  */
  161. echo_drain(effp, obuf, osamp)
  162. eff_t effp;
  163. long *obuf;
  164. long *osamp;
  165. {
  166.     echo_t echo = (echo_t) effp->priv;
  167.     struct    echoplex *e = echo->echoplex;
  168.     long l;
  169.     int i, j, done;
  170.  
  171.     i = e->counter;
  172.     done = 0;
  173.     /* drain out delay samples */
  174.     do {
  175.         l = 0;
  176.         for ( j = 0; j < e->numdelays; ++j )
  177.             l += 
  178. e->delaybuf[(i + e->maxsamples - e->samples[j]) % e->maxsamples] * e->atten[j];
  179.         l = clip24(l);
  180.         e->delaybuf[i] = l;
  181.         obuf[done++] = l * 256;
  182.         e->pppl = e->ppl;
  183.         e->ppl = e->pl;
  184.         e->pl = l;
  185.         i++;        /* need a % maxsamples here ? */
  186.         i %= e->maxsamples;
  187.     } while((done < *osamp) && 
  188.         ((abs(e->pl) + abs(e->ppl) + abs(e->pppl)) > FADE_THRESH));
  189.     e->counter = i;
  190.     *osamp = done;
  191.     /* drain will not be called again */
  192. }
  193.  
  194. /*
  195.  * Clean up echo effect.
  196.  */
  197. echo_stop(effp)
  198. eff_t effp;
  199. {
  200.     echo_t echo = (echo_t) effp->priv;
  201.  
  202.     free((char *) echo->echoplex);
  203.     echo->echoplex = (struct echoplex *) -1;   /* guaranteed core dump */
  204. }
  205.  
  206. long
  207. clip24(l)
  208. long l;
  209. {
  210.     if (l >= ((long)1 << 24))
  211.         return ((long)1 << 24) - 1;
  212.     else if (l <= -((long)1 << 24))
  213.         return -((long)1 << 24) + 1;
  214.     else
  215.         return l;
  216. }
  217.  
  218.  
  219.